#include "Transform.h"

mtBEGIN(TransformDef)
	mtCONSTRUCTOR();
	mtVARIABLE(x);
	mtVARIABLE(y);
	mtVARIABLE(angle);
mtEND

mtBEGIN(Transform)
	mtBASE(ECS::Component);
	mtCONSTRUCTOR();
	mtMETHOD(initWith);
mtEND

Transform::Transform() : _position(0.0f, 0.0f), _angle(0.0f)
{

}

TransformClient* Transform::createClient(TransformClient::updateFunction_t foo)
{
	TransformClient* client = new TransformClient(this);
	client->updateFunction = foo;
	_clients.push_back(client);
	client->updateFunction(_position, _angle);

	return client;
}

void Transform::setTransform( TransformClient* sender, const ECS::Vec2<float>& position, float angle )
{
	_position = position;
	_angle = angle;
	NotifyClientsExceptOf(sender);
}

void Transform::NotifyClientsExceptOf( TransformClient* sender /*= nullptr*/ )
{
	for (size_t i = 0; i < _clients.size(); ++i)
	{
		if (_clients[i] != sender)
			_clients[i]->updateFunction(_position, _angle);
	}
}

void Transform::setPosition( float x, float y )
{
	setPosition(ECS::Vec2<float>(x, y));
}

void Transform::setPosition(const ECS::Vec2<float>& position)
{
	_position = position;
	NotifyClientsExceptOf();
}

const ECS::Vec2<float>& Transform::getPosition() const
{
	return _position;
}

void Transform::setAngle( float angle )
{
	_angle = angle;
	NotifyClientsExceptOf();
}

bool Transform::initWith( TransformDef* def )
{
	_position = ECS::Vec2<float>(def->x, def->y);
	_angle = def->angle.hasValue() ? def->angle.value() : 0.0f;
	return true;
}

TransformClient::TransformClient( Transform* t )
{
	_transform = t;
}

void TransformClient::setTransform( const ECS::Vec2<float>& position, float angle )
{
	_transform->setTransform(this, position, angle);
}
